package com.ls.lserp.modules.custom.web;

import com.ls.lserp.common.beanvalidator.BeanValidators;
import com.ls.lserp.common.config.Global;
import com.ls.lserp.common.persistence.AjaxDone;
import com.ls.lserp.common.persistence.BaseEntity;
import com.ls.lserp.common.persistence.Page;
import com.ls.lserp.common.utils.CollectionsUtils;
import com.ls.lserp.common.utils.ResourcesUtil;
import com.ls.lserp.common.utils.StringUtils;
import com.ls.lserp.common.utils.excel.ExportExcel;
import com.ls.lserp.common.utils.excel.ImportExcel;
import com.ls.lserp.common.web.BaseController;
import com.ls.lserp.modules.custom.service.FitPropertyService;
import  com.ls.lserp.modules.order.entity.FitProperty;
import freemarker.template.Configuration;
import org.apache.commons.collections.map.HashedMap;
import org.apache.poi.openxml4j.exceptions.InvalidFormatException;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.ui.freemarker.FreeMarkerTemplateUtils;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.servlet.mvc.support.RedirectAttributes;
import org.springframework.web.servlet.support.RequestContext;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import javax.validation.ConstraintViolationException;
import java.io.IOException;
import java.util.*;

/**
  * @ClassName: FitpropertyController
  * @Description: 
  * 
  * @author 曹学海
  * @date 2016年11月11日 上午11:36:37
  *
  */

@Controller
@RequestMapping(value = "${adminPath}/custom/fitproperty")
public class FitpropertyController extends BaseController {
	
	@Autowired
	// 保存 编辑 删除 方法
	private FitPropertyService fitpropertyService;
	
	// 子项session
	private final String FITPROPERTYSUBLIST="fitpropertySubList";

	@Autowired
	Configuration freemarkerConfiguration;
	/**
	  * @Title: get
	  * @Description: 获取量体信息
	  * @param @param id
	  * @param @return
	  * @return FitProperty 
	  * @throws
	  */
	
	@ModelAttribute
	public FitProperty get(@RequestParam(required=false) String id) {
		
		// 判断id是否为空
		if (StringUtils.isNotBlank(id)){
			
			// 执行查询语句 查询基本信息
			return fitpropertyService.get(Long.parseLong(id));
		}else{
			
			// 若为空，实例化
			return new FitProperty();
		}
	}
	@RequiresPermissions("custom:fitproperty:view")
	@RequestMapping(value = {""})
	public String List(){
		// 返回页面地址
		return "modules/custom/fitProperty/fitPropertyList";
	}
	
    /**
      * @Title: list
      * @Description: 一览页面信息查询
      * @param @param fitproperty
      * @param @param request
      * @param @param response
      * @param @param model
      * @param @return
      * @return String 
      * @throws
      */
    
    @RequiresPermissions("custom:fitproperty:view")
    @RequestMapping(value = {"searchList"})
	@ResponseBody
    public String searchList(FitProperty fitProperty, HttpServletRequest request, HttpServletResponse response, Model model,String[] values) throws Exception {
		Map<Object, Object> listMap = new HashMap<Object, Object>();
		// ajax回调时使用的一览list名
		request.setAttribute(Global.LIST_NAME, "fitProperty");
		// 画面取得的检索项目
		String styleCategoryCD = fitProperty.getStyleCategoryCd();
		String searchParam = "&styleCategoryCD=" + styleCategoryCD;
		//放到Attribute里，使用Global类里面的SEARCH_PAEAM作为key
		request.setAttribute(Global.SEARCH_PAEAM, searchParam);
    	// 查询一览页面数据
    	Page<FitProperty> page = fitpropertyService.findList(new Page<FitProperty>(request, response), fitProperty);
		// 读取文件生成字符串
		String strUri = request.getContextPath() + Global.getAdminPath();
		String strHtml = "";
		Map<String, Object> map = new HashedMap();
		map.put("adminUri", strUri);
		map.put("fitpropertyList", page.getList());
		map.put("pageNo", page.getPageNo());
		map.put("pageSize", page.getPageSize());
		map.put("springMacroRequestContext", new RequestContext(request));
		strHtml = FreeMarkerTemplateUtils.processTemplateIntoString(freemarkerConfiguration.getTemplate ("fitpropertyList.ftl"),map);
		listMap.put("fitProperty", strHtml);
		listMap.put("page", page.getHtml());
		// ajax返回结果
		return renderString(response, listMap);
    }

	/**
	  * @Title: form
	  * @Description: 新建及编辑
	  * @param @param fitproperty
	  * @param @param redirectAttributes
	  * @param @param model
	  * @param @return
	  * @return String 
	  * @throws
	  */
	
	@RequiresPermissions("custom:fitproperty:edit")
	@RequestMapping(value = "form")
	public String form(FitProperty fitproperty,RedirectAttributes redirectAttributes, Model model,HttpSession session) {
	    
		// 新建判断 若不为null 编辑数据
		if(fitproperty.getId()!=null){
	    	
			// 实力化子项实体类
			FitProperty fitpropertySub = new FitProperty();
	    	
			// 给子项实体类赋值（关联值——项目值）
			fitpropertySub.setPropertyValue(fitproperty.getPropertyValue());
	        
			// 执行查询方法查询子项数据
			List<FitProperty> fitpropertyList= fitpropertyService.findSubFitProperty(fitpropertySub);
	        
			// 将子项数据list 赋值给mvc model层返回给jsp页面
			model.addAttribute("fitpropertyList", fitpropertyList);
			
			// 将list赋值给FITPROPERTYSUBLIST放入缓存中
	        session.setAttribute(FITPROPERTYSUBLIST, fitpropertyList);
	    }else{
	    	// 清空创建的子项
            session.setAttribute(FITPROPERTYSUBLIST, new ArrayList<FitProperty>());
	    }
		
		// 将实体类值赋给mvc model层返回jsp页面
		model.addAttribute("fitproperty", fitproperty);
		
		// 返回页面地址
		return "modules/custom/fitProperty/fitPropertyEdit";
	}

	/**
	  * @Title: formSub
	  * @Description: 新建子页面
	  * @param @param fitproperty
	  * @param @param redirectAttributes
	  * @param @param model
	  * @param @return
	  * @return String 
	  * @throws
	  */
	
	@RequiresPermissions("custom:fitproperty:edit")
	@RequestMapping(value = "formSub")
	public String formSub(FitProperty fitproperty,RedirectAttributes redirectAttributes, Model model,HttpSession session) {
		
		int delIndex=fitproperty.getDelIndex();
		String propertyCd=fitproperty.getPropertyCd();
        if(delIndex!=-1){
            // 获取当前创建的子项
            List<FitProperty> listSubItems = (List<FitProperty>) session.getAttribute(FITPROPERTYSUBLIST);
            fitproperty=listSubItems.get(delIndex);
            fitproperty.setDelIndex(delIndex);
            fitproperty.setPropertyCd(propertyCd);
            
        }
		
		// 新建子项 将FitProperty实体类赋给mvc model层 返回jsp页面
		model.addAttribute("fitproperty", fitproperty);
		
		// 返回页面地址
		return "modules/custom/fitProperty/fitPropertySubEdit";
	}

	
	/**
	  * @Title: checkName
	  * @Description: 查重
	  * @param @param propertyValue
	  * @param @param propertyOldValue
	  * @param @return
	  * @return String 
	  * @throws
	  */
	
	@RequiresPermissions("custom:fitproperty:edit")
	@ResponseBody
	@RequestMapping(value = "checkPropertyValue")
	public String checkPropertyValue(String oldPropertyValue,String propertyValue) {
		
        try {
        	// 页面获取数据值与旧数据若相同，并且数据值不为null
            if (propertyValue != null && propertyValue.toUpperCase().equals(oldPropertyValue.toUpperCase())) {
            	// 返回true
                return "true";
            // 页面获取数据值与旧数据若不相同，查询结果为null，并且数据值不为null
            } else if (propertyValue != null&& fitpropertyService.getPropertyValue(propertyValue) == null&&fitpropertyService.getPropertyCd(propertyValue) == null) {
            	// 返回true
            	return "true";
            }
            // 数据值重名
            return "false";

        } catch (Exception e) {
            // 记录日志
            logger.error(e.getMessage(), e);
        }
        // 数据值重名
        return "false";
	}
	
	/**
	  * @Title: checkName
	  * @Description: 查重
	  * @param @param propertyValue
	  * @param @param propertyOldValue
	  * @param @return
	  * @return String 
	  * @throws
	  */
	
	@RequiresPermissions("custom:fitproperty:edit")
	@ResponseBody
	@RequestMapping(value = "checkPropertyCd")
	public String checkPropertyCd(String oldPropertyCd,String propertyCd) {
		
       try {
       	// 页面获取数据代码与旧数据代码若相同，并且数据值不为null
           if (propertyCd != null && propertyCd.toUpperCase().equals(oldPropertyCd.toUpperCase())) {
           	// 返回true
               return "true";
           // 页面获取数据代码与旧数据代码若不相同，查询结果为null，并且数据值不为null
           } else if (propertyCd != null&& fitpropertyService.getPropertyCd(propertyCd) == null) {
           	// 返回true
           	return "true";
           }
           // 数据代码重名
           return "false";

       } catch (Exception e) {
           // 记录日志
           logger.error(e.getMessage(), e);
       }
       // 数据代码重名
       return "false";
	}
	
		/**
		  * @Title: save
		  * @Description: 保存
		  * @param @param fitproperty
		  * @param @param request
		  * @param @param model
		  * @param @param response
		  * @param @return
		  * @return String 
		  * @throws
		  */
		
		@RequiresPermissions("custom:fitproperty:edit")
		@RequestMapping(value = "save")
		@ResponseBody
		public String save(FitProperty fitproperty, HttpServletRequest request, Model model, HttpServletResponse response, HttpSession session) {
			
			// 判断id是否为null （判断新建或修改）
			if(fitproperty.getId()!=null){
			    // 编辑数据
				// 判断数据是否删除
				FitProperty fitpropertyNew=get(fitproperty.getId().toString());
				
	            // 判断数据是否删除
				if(fitpropertyNew==null || BaseEntity.DEL_FLAG_DELETE.equals(fitpropertyNew.getDeleteFlag())){
	                
					// 返回提示信息
					return renderString(response,AjaxDone.error(getText("This_record_has_been_deleted_or_modified_the_operation_failed")));
	            }
				
				// 排他处理
			    if(fitproperty.getVersion()==get(fitproperty.getId().toString()).getVersion()){
			    	// 版本号加1
			    	fitproperty.setVersion(fitproperty.getVersion()+1);
			    }else{
			    	
			    	// 同时操作该数据返回提示信息
			        return renderString(response,AjaxDone.error(getText("This_record_has_been_deleted_or_modified_the_operation_failed")));
			    }
			}else{
				
				// 新建量体项目版本号赋值1
				fitproperty.setVersion(1L);
			}
			
			try {
				
				// 通过缓存将子项值赋给list
	            List<FitProperty> list = (List<FitProperty>) session.getAttribute(FITPROPERTYSUBLIST);
	            
	            // 将list赋给子项list
	            fitproperty.setFitpropertyList(list);
	            
	            // 若启用未选择赋值1
				if(fitproperty.getEnableFlag()==null){
					fitproperty.setEnableFlag("1");
				}
				
			    // 保存量体信息
				fitpropertyService.saveFitProperty(fitproperty);
				
				// 清空缓存,实例化
				session.setAttribute(FITPROPERTYSUBLIST, new ArrayList<FitProperty>());
		        
				// 保存成功返回提示信息
				return renderString(response,AjaxDone.ok(ResourcesUtil.getFormatProperties("messages", "fitpropertySaveSuccess", new String[]{fitproperty.getPropertyValue()})));
			 } catch (Exception e) {
		           // 记录日志
		           logger.error(e.getMessage(), e);
				 // 提示错误信息
		         return renderString(response,AjaxDone.error(getText("System_error_please_contact_your_administrator")));
		     }
		}

    
    
    
    /**
      * @Title: show
      * @Description: 查看页面
      * @param @param fitproperty
      * @param @param model
      * @param @return
      * @return String 
      * @throws
      */

	@RequiresPermissions("custom:fitproperty:view")
	@RequestMapping(value = "show")
	public String show(FitProperty fitproperty, Model model) {

		// 实例化子项
		FitProperty fitpropertySub = new FitProperty();

		// 将项目值赋给子项实体类
		fitpropertySub.setPropertyValue(fitproperty.getPropertyValue());

		// 执行查询语句
		List<FitProperty> fitpropertyList= fitpropertyService.findSubFitProperty(fitpropertySub);

		// 将查询结果赋值mvc model层返回jsp页面
		model.addAttribute("fitpropertyList", fitpropertyList);

		// 将查询结果赋值mvc model层返回jsp页面
		model.addAttribute("fitproperty", fitproperty);

		// 返回页面地址
		return "modules/custom/fitProperty/fitPropertyShow";
	}
    
    
    /**
      * @Title: delete
      * @Description: 逻辑删除
      * @param @param fitproperty
      * @param @param response
      * @param @return
      * @return String 
      * @throws
      */
    
    @RequiresPermissions("custom:fitproperty:edit")
	@RequestMapping(value = "delete")
	public String delete(FitProperty fitproperty, HttpServletResponse response) {
		
		    try {
		    	
		    	// 执行逻辑删除方法
		    	fitpropertyService.deleteFitProperty(fitproperty);
            } catch (Exception e) {
                // 记录日志
                logger.error(e.getMessage(), e);
            	// 提示错误信息
                return renderString(response,AjaxDone.error(getText("System_error_please_contact_your_administrator")));
            }
		    
		    // 提示删除成功信息
			return renderString(response,AjaxDone.ok(getText("fitproperty_delete_success")));
    }
    

    /**
      * @Title: searchSubList
      * @Description: 根据父项value,查找相关子项
      * @param @param fitproperty
      * @param @param model
      * @param @param session
      * @param @return
      * @return String 
      * @throws
      */
    
    @RequiresPermissions("custom:fitproperty:view")
    @RequestMapping(value = "searchSubList")
    public String searchSubList(FitProperty fitproperty, Model model, HttpSession session) {
        try {
            // 通过缓存赋值给子项list
            List<FitProperty> fitpropertyList = (List<FitProperty>) session.getAttribute(FITPROPERTYSUBLIST);
            
            // 将list赋值给 mvc model层返回jsp页面
            model.addAttribute("fitpropertyList", fitpropertyList);
            
            // 返回地址
            return "modules/custom/fitProperty/fitPropertyEdit";
        } catch (Exception e) {
            // 记录日志
            logger.error(e.getMessage(), e);
        	// 发生异常 不返回
            return null;
        }


    }
    
    
    /**
      * @Title: deleteSub
      * @Description: 删除缓存子项数据
      * @param @param fitproperty
      * @param @param model
      * @param @param session
      * @param @return
      * @return String 
      * @throws
      */
    
    @RequiresPermissions("custom:fitproperty:edit")
    @RequestMapping(value = "deleteSub")
    public String deleteSub(FitProperty fitproperty, Model model,HttpSession session ) {
        try {
            // 通过缓存获取子项数据
            List<FitProperty> fitpropertyList = (List<FitProperty>) session.getAttribute(FITPROPERTYSUBLIST);
            int delIndex = fitproperty.getDelIndex();
            fitpropertyList.get(delIndex).setDeleteFlag("1");
            // 在session里重新存入子项
            session.setAttribute(FITPROPERTYSUBLIST, fitpropertyList);
            
            // 将list赋值给mvc model层返回jsp 页面
            model.addAttribute("fitpropertyList", fitpropertyList);
            
            // 返回地址
            return "modules/custom/fitProperty/fitPropertyEdit";
        } catch (Exception e) {
            // 记录日志
            logger.error(e.getMessage(), e);
            // 返回地址
            return "modules/custom/fitProperty/fitPropertyEdit";
        }
        
    }
    
    
    /**
      * @Title: saveSub
      * @Description: 保存子项数据赋值给缓存list
      * @param @param fitproperty
      * @param @param request
      * @param @param model
      * @param @param response
      * @param @param session
      * @param @return
      * @return String 
      * @throws
      */
    
    @RequiresPermissions("custom:fitproperty:edit")
    @RequestMapping(value = "saveSub")
    @ResponseBody
    public String saveSub(FitProperty fitproperty, HttpServletRequest request, Model model, HttpServletResponse response,HttpSession session){
        try {
            // 通过缓存获取list数据
            List<FitProperty> fitpropertyList = (List<FitProperty>) session.getAttribute(FITPROPERTYSUBLIST);
        
            // 将新的实体类添加到list中
            int delIndex=fitproperty.getDelIndex();
            
            if(delIndex==-1){
            	fitpropertyList.add(fitproperty); 
            }else{
				//项目值
				fitpropertyList.get(delIndex).setPropertyValue(fitproperty.getPropertyValue());
				//项目单位
				fitpropertyList.get(delIndex).setPropertyUnitCd(fitproperty.getPropertyUnitCd());
				//中文全称
				fitpropertyList.get(delIndex).setPropertyNameCn(fitproperty.getPropertyNameCn());
				//英文全称
				fitpropertyList.get(delIndex).setPropertyNameEn(fitproperty.getPropertyNameEn());
				//日文全称
				fitpropertyList.get(delIndex).setPropertyNameJp(fitproperty.getPropertyNameJp());
				//试穿调整项目
				fitpropertyList.get(delIndex).setFitUseTypeCd(fitproperty.getFitUseTypeCd());
				//增加范围
				fitpropertyList.get(delIndex).setPropertyInFrom(fitproperty.getPropertyInFrom());
				fitpropertyList.get(delIndex).setPropertyInTo(fitproperty.getPropertyInTo());
				//缩减范围
				fitpropertyList.get(delIndex).setPropertyOutFrom(fitproperty.getPropertyOutFrom());
				fitpropertyList.get(delIndex).setPropertyOutTo(fitproperty.getPropertyOutTo());
				//状态
				fitpropertyList.get(delIndex).setEnableFlag(fitproperty.getEnableFlag());
				//备注
				fitpropertyList.get(delIndex).setRemarks(fitproperty.getRemarks());
            }
            
            // 将list赋值给缓存session
            session.setAttribute(FITPROPERTYSUBLIST, fitpropertyList);
        
            // 返回true
            return "true";
        
        }catch(Exception e){
            // 记录日志
            logger.error(e.getMessage(), e);
        	// 抛异常返回false
            return "false";
        }
        
    }
    
    
    /**
     * 下载导入量体项目模板
     * @param response
     * @param redirectAttributes
     * @return
     */
    @RequiresPermissions("custom:fitproperty:view")
    @RequestMapping(value = "import/template")
    public String importFileTemplate(HttpServletResponse response) {
        try {
            String fileName = getText("fitproperty_importTemplate");
            FitProperty fitproperty=new FitProperty();
            List<FitProperty> list = fitpropertyService.findAllListExport(fitproperty); 
            
            // fitproperty_msg04 :量体项目
            new ExportExcel(getText("fitproperty_msg04"), FitProperty.class, 2).setDataList(list).write(response, fileName).dispose();
            return null;
        } catch (Exception e) {
            // 记录日志
            logger.error(e.getMessage(), e);
        }
        
        // 提示错误信息
        return renderString(response,AjaxDone.error(getText("System_error_please_contact_your_administrator")));
      
    }
    /**
     * 导入量体项目
     * @param file
     * @param redirectAttributes
     * @return
     * @throws IOException 
     * @throws InvalidFormatException 
     * @throws IllegalAccessException 
     * @throws InstantiationException 
     */
    @RequiresPermissions("custom:fitproperty:edit")
    @RequestMapping(value = "import", method=RequestMethod.POST)
    @ResponseBody
    public String importFile(MultipartFile file, HttpServletResponse response)throws InvalidFormatException, IOException, InstantiationException,IllegalAccessException {
        Integer successNum = 0;
        Integer failureNum = 0;
        StringBuilder failureMsg = new StringBuilder();
        ImportExcel ei = new ImportExcel(file, 1, 0);
        List<FitProperty> list = ei.getDataList(FitProperty.class);

        // 判断数据值是否重复
        Set set = new HashSet(CollectionsUtils.extractToList(list, "propertyValue"));
        if (list.size() != set.size()) {
            failureMsg.append("<br/>" + getText("fitproperty_msg02"));
            return renderString(response, AjaxDone.error(failureMsg.toString()));
        }

        for (FitProperty fitproperty : list) {
            try {
                if (StringUtils.isBlank(fitproperty.getPropertyValue())
                        || StringUtils.isBlank(fitproperty.getPropertyNameCn())
                        || StringUtils.isBlank(fitproperty.getPropertyNameEn())
                        || StringUtils.isBlank(fitproperty.getPropertyNameJp())) {
                    // fitproperty_msg01 :必填项数据存在空值，请检查数据！
                    return renderString(response,
                            AjaxDone.error(getText("fitproperty_msg01")));
                }
            } catch (ConstraintViolationException ex) {
                // 记录日志
                logger.error(ex.getMessage(), ex);
                // fitproperty_msg04 :量体项目 fitproperty_msg05: 导入失败：
                failureMsg.append("<br/>" + getText("fitproperty_msg04")+ fitproperty.getItemCD() + "-" + fitproperty.getPropertyValue()+ getText("fitproperty_msg05"));
                List<String> messageList = BeanValidators.extractPropertyAndMessageAsList(ex, ": ");
                for (String message : messageList) {
                    failureMsg.append(message + "; ");
                    failureNum++;
                }
            } catch (Exception ex) {
                // 记录日志
                logger.error(ex.getMessage(), ex);
                // fitproperty_msg04: 量体项目fitproperty_msg05: 导入失败：
                failureMsg.append("<br/>" + getText("fitproperty_msg04")+ fitproperty.getItemCD() + "-" + fitproperty.getPropertyValue()+ getText("fitproperty_msg05") + ex.getMessage());
            }
        }
        if (failureNum > 0) {
            // fitproperty_msg06:，失败fitproperty_msg07:条量体项目数据，导入信息如下：
            failureMsg.insert(0, getText("fitproperty_msg06") + failureNum+ getText("fitproperty_msg07"));
            return renderString(response,AjaxDone.error(getText("System_error_please_contact_your_administrator")+ failureMsg.toString()));
        } else {
            successNum = fitpropertyService.saveFitPropertyImport(list);
            // fitproperty_msg08:已成功导入fitproperty_msg09:条量体项目数据"
            return renderString(response,AjaxDone.ok(getText("fitproperty_msg08") + successNum+ getText("fitproperty_msg09")));
        }
    }
    
    
	public FitPropertyService getFitpropertyService() {
		return fitpropertyService;
	}


	public void setFitpropertyService(FitPropertyService fitpropertyService) {
		this.fitpropertyService = fitpropertyService;
	}


    
    
}
